/*
 * <<
 * Davinci
 * ==
 * Copyright (C) 2016 - 2017 EDP
 * ==
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * >>
 */

import React, { useEffect, useState } from 'react';
import { connect } from 'umi';
import {
  GlobalControlQueryMode,
  IControlRelatedField,
  IFormedView,
  IFormedViews,
  IGlobalControl,
  IGlobalControlRelatedItem,
  IViewModelProps,
} from '../types';
import { RadioChangeEvent } from 'antd/lib/radio';
import FilterList from './FilterList';
import { Button, Form, Modal, Radio } from 'antd';
import RelatedInfoSelectors from '@/pages/Analysis/Board/components/Filters/config/RelatedInfoSelectors';
import { getDefaultGlobalControl, getFormedView, getRelatedFieldsInfo } from '../util';
import { ConnectState } from '@/models/connect';
import { IDashboardItem } from '@/pages/SelfQuery/type';
import { ISheetItem } from '@/pages/Analysis/type';
import FilterForm from './FilterForm';
import styles from '../index.less';

const RadioGroup = Radio.Group;
const RadioButton = Radio.Button;


require('../index.less');


export interface IRelatedItemSource extends IGlobalControlRelatedItem {
  id: number
  name: string
}

export interface IRelatedViewSource {
  id: number
  name: string
  model: IViewModelProps[]
  fields: IControlRelatedField | IControlRelatedField[]
}

interface IGlobalControlConfigProps {
  board: IDashboardItem
  sheetList: ISheetItem[]
  visible: boolean
  loading?: boolean
  onCancel: () => void
  onSave: (filterItems: any[], queryMode: GlobalControlQueryMode) => void
}


const GlobalControlConfig: React.FC<IGlobalControlConfigProps> = (props: IGlobalControlConfigProps) => {
  const { sheetList, board, loading, visible, onCancel, onSave } = props;
  const { widgets } = board;
  const [selected, setSelected] = useState<IGlobalControl | any>();
  const [controls, setControls] = useState<IGlobalControl[]>([]);
  const [queryMode, setQueryMode] = useState<GlobalControlQueryMode>(GlobalControlQueryMode.Immediately);
  //当前看板的所有指标
  const [itemSelectorSource, setItemSelectorSource] = useState<IRelatedItemSource[]>([]);
  const [viewSelectorSource, setViewSelectorSource] = useState<IRelatedViewSource[]>([]);
  const [views, setViews] = useState<IFormedViews>({});
  const [filterForm] = Form.useForm();
  useEffect(() => {
    let items: any = [];
    let selected
    if (board && board.config) {
      const filters = JSON.parse(board.config);
      let filterList = [];
      if (filters && filters.filters) {
        filterList = filters.filters;
      }
      setControls(filterList);
      // eslint-disable-next-line prefer-destructuring
      selected = filterList[0];
      setSelected(selected)
      const { relatedItems } = selected;
      items = widgets ? widgets.map(v => {
        const { checked } = relatedItems[v.id] ? relatedItems[v.id] : { checked: false };
        return { id: v.id, name: v.widgetName, checked, viewId: v.viewId };
      }) : [];

    }
    if (sheetList) {
      const views: IFormedViews = sheetList.reduce((acc, view) => {
        const { id, model } = getFormedView(view);
        acc[id] = {
          ...view,
          model,
        };
        return acc;
      }, [] as IFormedViews);
      setViews(views);
      views && Object.keys(views).length && setViewSelectorSource(getViewSelectorSource(items, selected, views))
      setItemSelectorSource(items);
    }
  }, [board, sheetList]);
  useEffect(() => {
    visible && setSelected(controls[0]);
  }, [visible]);


  /**
   * 修改当前筛选项的名称
   * @param key
   */
  const changeName = (key: any) => (name: any) => {
    setControls(controls.map((c: any) => (c.key === key
      ? { ...c, name }
      : c)));
  };
  console.log('controls', controls);
  const getViewSelectorSource = (
    itemSelectorSource: IRelatedItemSource[],
    control: IGlobalControl,
    views: IFormedViews,
  ) => {
    if (!control) {
      return [];
    }
    const { relatedViews, type, interactionType } = control;
    const selectedItemRelatedViews: IFormedViews = itemSelectorSource
      .filter((s) => s.checked)
      .reduce<IFormedViews>((viewObj, itemSource) => {
        if (!viewObj[itemSource.viewId]) {
          viewObj[itemSource.viewId] = views[itemSource.viewId];
        }
        return viewObj;
      }, {});
    return Object.entries(selectedItemRelatedViews)
      .map(([viewId, view]: [string, IFormedView]) => ({
        id: Number(viewId),
        name: view.name,
        ...getRelatedFieldsInfo(view, type, interactionType, relatedViews[view.id]),
      }));
  };
  const itemCheck = (id: number) => () => {
    const itemSelectorSourceNew = itemSelectorSource.map((s) => {
      return s.id === id
        ? {
          ...s,
          checked: !s.checked,
        }
        : s;
    });
    setItemSelectorSource(itemSelectorSourceNew);
    setViewSelectorSource(getViewSelectorSource(itemSelectorSourceNew, selected, views));
  };
  const toggleCheckAll = () => {

    const allChecked = itemSelectorSource.every((s) => s.checked);
    const itemSelectorSourceNew = itemSelectorSource.map((a) => ({
      ...a,
      checked: !allChecked,
    }));
    setItemSelectorSource(itemSelectorSourceNew);
    setViewSelectorSource(getViewSelectorSource(itemSelectorSourceNew, selected, views));
  };
  const getCachedFormValues = (
    resolve?: (err: any, cachedControls?: any) => void,
  ) => {


    const values = filterForm.getFieldsValue();
    const { key, defaultValue } = values;
    const cachedControls = controls.map((c) => {
      if (c.key === key) {
        return {
          ...c,
          ...values,
          interactionType: selected.interactionType,
          defaultValue,
          relatedItems: itemSelectorSource.reduce((obj, source) => {
            obj[source.id] = {
              viewId: source.viewId,
              checked: source.checked,
            };
            return obj;
          }, {}),
          relatedViews: viewSelectorSource.reduce((obj, source) => {
            obj[source.id] = source.fields;
            return obj;
          }, {}),
        };
      }
      return c;

    });
    resolve && resolve(null, cachedControls);

  };
  const changeQueryMode = (e: RadioChangeEvent) => {
    setQueryMode(e.target.value);
  };
  const save = () => {
    if (controls.length > 0) {
      getCachedFormValues((err, cachedControls) => {
        if (err) {
          return;
        }
        console.log('save', cachedControls, queryMode);
        onSave(cachedControls, queryMode);
      });
    } else {
      onSave([], queryMode);
    }
  };

  const selectFilter = (key: string) => {

    getCachedFormValues((err, conts) => {
      if (err) {
        return;
      }
      const selected = conts.find((c: any) => c.key === key);
      setSelected(selected);
      console.log('getCachedFormValues----')
      setControls(conts);
      setRelatedInfo(selected, widgets, views);
    });
  };
  const modelOrVariableSelect = (id: number) => (value: string | string[]) => {
    selected && setViewSelectorSource(
      viewSelectorSource.map((v) => {
        if (v.id === id) {
          let fields;
          let detail = v.model.find((m) => m.name === value);
          if (detail) {
            fields = {
              name: detail.name,
              type: detail.sqlType,
            };
            return {
              ...v,
              fields,
            };
          }
          return {
            ...v,
          };
        }
        return v;

      }),
    );
  };
  const setRelatedInfo = (control: IGlobalControl, widgets: any[], views: IFormedViews) => {
    if (control) {
      const { relatedItems } = control;
      const itemSelectorSource: IRelatedItemSource[] = widgets.map((i) => {
        return {
          id: i.id,
          name: i.widgetName,
          viewId: i.viewId,
          checked: relatedItems[i.id] ? relatedItems[i.id].checked : false,
        };
      });
      const viewSelectorSource = getViewSelectorSource(itemSelectorSource, control, views);
      setItemSelectorSource(itemSelectorSource);
      setViewSelectorSource(viewSelectorSource);
    }
  };
  /**
   * 添加一个筛选项
   */
  const addFilter = () => {
    console.log('addFilter----')
    const newFilter: IGlobalControl = getDefaultGlobalControl();
    setControls([...controls, newFilter]);
    setSelected(newFilter);
    if (selected) {
      getCachedFormValues((err, cachedControls) => {
        if (err) {
          return;
        }
        setControls([...cachedControls, newFilter]);
        setSelected(newFilter);
        setRelatedInfo(newFilter, widgets, views);
      });
    } else {
      setControls([...controls, newFilter]);
      setSelected(newFilter);
      setRelatedInfo(newFilter, widgets, views);
    }
  };
  const resetForm = () => {
    setSelected(null);
  };
  const deleteFilter = (reselectedKey: string) => {
    console.log('deleteFilter----')

    const reselected = controls.find((c) => c.key === reselectedKey);
    setControls(controls.filter((c) => c.key !== reselectedKey));
    setSelected(reselected);
  };
  const modalFooter = [(
    <RadioGroup
      key='queryMode'
      className={styles.queryMode}
      value={queryMode}
      onChange={changeQueryMode}
    >
      <RadioButton value={GlobalControlQueryMode.Immediately}>立即查询</RadioButton>
      <RadioButton value={GlobalControlQueryMode.Manually}>手动查询</RadioButton>
    </RadioGroup>
  ), (
    <Button
      key='cancel'
      size='large'
      onClick={onCancel}
    >
      取 消
    </Button>
  ), (
    <Button
      key='submit'
      size='large'
      type='primary'
      loading={loading}
      disabled={loading}
      onClick={save}
    >
      保 存
    </Button>
  )];

  return (
    <Modal
      wrapClassName='ant-modal-large ant-modal-center'
      title='全局控制器配置'
      maskClosable={false}
      visible={visible}
      footer={modalFooter}
      onCancel={onCancel}
      afterClose={resetForm}
    >
      <div className={styles.filterConfig}>
        <div className={styles.left}>
          <FilterList
            list={controls}
            selectedFilter={selected}
            onSelectFilter={selectFilter}
            onAddFilter={addFilter}
            onDeleteFilter={deleteFilter}
            onNameChange={changeName}
          />
        </div>
        <div className={styles.center}>
          {
            selected && (
              <>
                <RelatedInfoSelectors
                  itemSelectorSource={itemSelectorSource}
                  viewSelectorSource={viewSelectorSource}
                  interactionType='column'
                  onItemCheck={itemCheck}
                  onModelOrVariableSelect={modelOrVariableSelect}
                  onToggleCheckAll={toggleCheckAll}
                />
                <FilterForm
                  selected={selected}
                  interactionType='column'
                  form={filterForm}
                />
              </>
            )
          }
        </div>
      </div>
    </Modal>
  );
};
export default connect(({ sheet }: ConnectState) => ({
  sheetList: sheet.sheetList,
}))(GlobalControlConfig);
